import { AbstractControl, NgForm, Validators } from "@angular/forms";
import { Injectable } from "@angular/core";
import { ValidateUtil } from "./validateutil";

/**
 * Form输入校验统一类
 */
/** 使用方式 *****************************************************
 * 1、组件中 导入 NzToolTipModule 以及 ValidateService和ValidateType
 * 2、在组件中注入服务 private validateService: ValidateService
 * 3、在对应的nz-form-control 加入 nz-tooltip [nzTooltipTitle]="validateDef.controlName.err"
 * 4、定义校验结构validateDef: any = { controlName:{validator: [ { type: ValidateType, value: any },... ]} , controlName2:{}, controlName3:{}...}
 *    controlName : 控件中属性name
 *    type: 使用枚举 ValidateType
 *    value: 有以下几种情况
 *        ValidateType 为 required,numeric,integer,email,qq,mobile,phone时，value为boolean型，true进行校验，false不校验
 *        ValidateType 为 minLength,maxLength,min,max时，value为数字，=-1时不进行校验
 *
 * 5、在保存方法调用this.validateService.validate(form: NgForm, validateDef: {});
 *    form : @ViewChild('checkForm', { static: true }) checkForm: NgForm;
 *    validateDef:上面定义的校验
 *    返回值为boolean，=true校验通过，=false 校验不通过
 *
 * 可参考 evl163-user-dialog.component
 *
 * 注意 nz-cascader 控件因比较特殊，目前不支持统一验证，需要自定义
 * ****************************************************************/
@Injectable({
  providedIn: 'root'
})
export class ValidateService {

  constructor() {
  }

  public validate(form: NgForm, validateDef: {}): boolean {
    for (let name in validateDef) {
      let vali: any = validateDef[name];
      let ctrl = form.controls[name];
      for (let i = 0; i < vali.validator.length; i++) {
        let itm: ValidateModel = vali.validator[i];
        if (itm.type == ValidateType.required && itm.value == true) {
          //自动清除两边空格
          if(ctrl.value) {
            ctrl.setValue(ctrl.value.replace(/^\s*|\s*$/g, ""));
          }
          ctrl.setValidators(Validators.required);
          vali.err = this.setError(ctrl, "该项不能为空，请输入");
          if (vali.err != "") {
            break;
          }
        } else if (itm.type == ValidateType.minLength && itm.value >= 0) {
          ctrl.setValidators(Validators.minLength(itm.value));
          vali.err = this.setError(ctrl, `该项最小输入长度为${ itm.value }`);
          if (vali.err != "") {
            break;
          }
        } else if (itm.type == ValidateType.maxLength && itm.value >= 0) {
          ctrl.setValidators(Validators.maxLength(itm.value));
          vali.err = this.setError(ctrl, `该项最大输入长度为${ itm.value }`);
          if (vali.err != "") {
            break;
          }
        } else if (itm.type == ValidateType.email && itm.value == true) {
          if (this.isVali(ctrl)) {
            continue;
          }
          ctrl.setValidators(Validators.email);
          vali.err = this.setError(ctrl, "输入不是Email格式，请重新输入");
          if (vali.err != "") {
            break;
          }
        } else if (itm.type == ValidateType.min && itm.value >= 0) {
          if (this.isVali(ctrl)) {
            continue;
          }
          ctrl.setValidators(Validators.min(itm.value));
          vali.err = this.setError(ctrl, `该项最小输入值为${ itm.value }`);
          if (vali.err != "") {
            break;
          }
        } else if (itm.type == ValidateType.max && itm.value >= 0) {
          if (this.isVali(ctrl)) {
            continue;
          }
          ctrl.setValidators(Validators.max(itm.value));
          vali.err = this.setError(ctrl, `该项最大输入值为${ itm.value }`);
          if (vali.err != "") {
            break;
          }
        } else if (itm.type == ValidateType.numeric && itm.value) {
          if (this.isVali(ctrl)) {
            continue;
          }
          ctrl.setValidators(Validators.pattern(ValidateUtil.RegNumeric));
          vali.err = this.setError(ctrl, `该项只能输入数字`);
          if (vali.err != "") {
            break;
          }
        } else if (itm.type == ValidateType.integer && itm.value) {
          if (this.isVali(ctrl)) {
            continue;
          }
          ctrl.setValidators(Validators.pattern(ValidateUtil.RegInteger));
          vali.err = this.setError(ctrl, `该项只能输入整数`);
          if (vali.err != "") {
            break;
          }
        } else if (itm.type == ValidateType.qq && itm.value) {
          if (this.isVali(ctrl)) {
            continue;
          }
          ctrl.setValidators(Validators.pattern(ValidateUtil.RegQQ));
          vali.err = this.setError(ctrl, `QQ号输入不正确`);
          if (vali.err != "") {
            break;
          }
        } else if (itm.type == ValidateType.mobile && itm.value) {
          if (this.isVali(ctrl)) {
            continue;
          }
          ctrl.setValidators(Validators.pattern(ValidateUtil.RegMobile));
          vali.err = this.setError(ctrl, `手机号输入不正确`);
          if (vali.err != "") {
            break;
          }
        } else if (itm.type == ValidateType.phone && itm.value) {
          if (this.isVali(ctrl)) {
            continue;
          }
          ctrl.setValidators(Validators.pattern(ValidateUtil.RegPhone));
          vali.err = this.setError(ctrl, `座机号码输入不正确`);
          if (vali.err != "") {
            break;
          }
        }
      }

    }
    // for (let i in form.controls) {
    //   form.controls[i].markAsDirty();
    //   form.controls[i].updateValueAndValidity();
    // }
    return form.valid;
  }

  private setError(ctrl: AbstractControl, errMsg: string): string {
    ctrl.markAsDirty();
    ctrl.updateValueAndValidity();
    if (ctrl.invalid) {
      return errMsg;
    } else {
      return "";
    }
  }

  private isVali(ctrl: AbstractControl): boolean {
    if (ctrl.value == null || ctrl.value == "") {
      return true;
    } else {
      return false;
    }
  }
}

export class ValidateModel {
  public type: ValidateType;
  public value: any;
}

/**
 * 用来定义其他的校验类型
 */
export enum ValidateType {
  // 必填
  required,
  // 数字
  numeric,
  // 整数
  integer,
  // 最小长度
  minLength,
  // 最大长度
  maxLength,
  // 邮箱地址
  email,
  // QQ号
  qq,
  // 手机号
  mobile,
  // 座机号
  phone,
  // 最小值
  min,
  // 最大值
  max
}
